Enterprise Objects Framework Release 1.1 Copyright ã1995 by NeXT Computer, Inc.  All Rights Reserved.

EOAttribute

Inherits From:	NSObject

Declared In:	eoaccess/EOAttribute.h

Class Description

An EOAttribute represents a value property of an EOEntity, and associates an internal name used by the client application with an external name or definition used by the database (usually a column in a table). The property an EOAttribute represents may be a meaningful value, such as a salary or a name, or it may be an arbitrary value used for identification but with no real-world applicability (ID numbers and foreign keys for relationships fall into this category). An EOAttribute maintains type information for binding values to the instance variables of enterprise objects.

You usually define attributes in your EOModel with the EOModeler application, which is documented in the Enterprise Objects Framework Developer's Guide, Chapter 5, ªUsing EOModeler.º EOAttributes are primarily used by the Enterprise Objects Framework for generation of proper SQL; your code will probably make limited use of EOAttributes unless you're working at the adaptor level.

An attribute may be simple, derived, or flattened. A simple attribute corresponds to a single column in the database, and may be read or updated directly from or to the database. A simple EOAttribute may also be set as read-only with its setReadOnly: method. Read-only attributes of enterprise objects are never updated, and aren't inserted with new objects.

A derived attribute doesn't correspond to a single database column in its entity's database table, and is usually based on some other attribute, which is modified in some way. For example, if an Employee entity has a simple monthly salary attribute, you can define a derived annualSalary attribute as ªsalary * 12º. Derived attributes, since they don't correspond to actual values in the database, are effectively read-only; it makes no sense to write a derived value.

A flattened attribute of an entity is actually an attribute of some other entity reached through a relationship; as such it's considered a kind of derived attribute. A flattened attribute's external definition is a data path ending in an attribute name. For example, if the Employee entity has the relationship toDepartment and the Department entity has the attribute name, you can define deptName as an attribute of your Employee EOEntity by creating an EOAttribute for it with a definition of ªtoDepartment.nameº. Flattened attributes are also read-only, because of an ambiguity that arises should one be edited: Is the attribute to be changed in the object to which it belongs, or does the editing mean that the object to which the attribute refers should be changed? The Framework doesn't make this decision, leaving it to you to edit the object that owns the flattened attribute or to change the value for the relationship through which the flattened attribute is defined.

Like the other major modeling classes, EOAttribute provides a user dictionary for the application to store any auxiliary information it needs.

Mapping from Database to Objects

Every EOAttribute has an external type, which is the type used by the database to store its associated data, and an Objective C class used as the type for that data in the client application. The type used by the database is accessed with the setExternalType: and externalType methods. The class type used by the application is accessed with the setValueClassName: and valueClassName methods. You can map database types to a set of standard value classes, which includes:

·	NSString
·	NSNumber
·	NSData
·	NSCalendarDate

Database-specific adaptors automatically handle value conversions for these classes. You can also create your own custom value class, so long as you define a format that it uses to interpret data. The methods for setting this custom value type are setValueType: and valueType. Your value class must also implement the EODatabaseCustomValues protocol to work as a custom value; see that protocol specification for more information.

The handling of dates assumes by default that both the database server and the client application are running in the same, local, time zone. You can alter either time zone with the setClientTimeZone: and setServerTimeZone:. If the server and client time zones are different, the adaptor automatically converts dates as they pass into and out of the server. An attribute can also define a string format for dates with the setCalendarFormat: method, so that enterprise objects can properly display dates to the user of the application. A calendar format specifies how the components of a date are to be displayed; for example, as ªJuly 10, 1984º or ª07/10/84.º See the NSDate class specification in the Foundation Kit for more information.

SQL Statement Formats

In addition to mapping database values to object values, an EOAttribute can alter the way values are selected, inserted, and updated in the database by defining special format strings. These format strings allow a client application to extend its reach right down to the server for certain operations. For example, you might want to view an employee's salary on a yearly basis, without defining a derived attribute as in a previous example. In this case, you could set the salary attribute's SELECT statement format to ªsalary * 12º and the INSERT and UPDATE statement formats to ªsalary / 12º. Thus, whenever your application retrieves values for the salary attribute they're multiplied by 12, and when it writes values back to the database they're divided by 12.

Your application can use any legal SQL value expression in a format string, and can even access server-specific features such as stored procedures. Accessing server-specific features can offer your application great flexibility in dealing with its server, but does limit its portability. You're responsible for ensuring that your SQL is well-formed and will be understood by the database server.

Creating a Simple Attribute

A simple attribute needs at least the following characteristics:

·	A name unique within its EOEntity
·	The name of a column in the database table for its entity (the external name)
·	A declaration of the type of that column as defined by the database and adaptor (the external type)
·	A declaration of the Objective C class used to represent values in the application
·	For Objective C value classes that require it, a subtype for such distinctions as between numeric types
·	For attributes defined as dates, a calendar format and time zone

You also have to set whether the attribute is part of its entity's primary key, is a class property, or is used for locking. See the EOEntity class description for more information on these three groups of attributes. This code excerpt gives an example of creating a simple EOAttribute and adding it to an EOEntity:

EOEntity *employeeEntity;    /* Assume this exists. */
EOAttribute *salaryAttribute;
NSArray *empClassProps;
NSArray *empLockAttributes;

salaryAttribute = [[EOAttribute alloc] initWithName:@"salary"];
[salaryAttribute setColumnName:@"SALARY"];
[salaryAttribute setExternalType:@"money"];
[salaryAttribute setValueClassName:"NSNumber"];
[salaryAttribute setValueType:@"d"];
[employeeEntity addAttribute:salaryAttribute];
[salaryAttribute release];

empClassProps = [[employeeEntity classProperties] mutableCopy];
[empClassProps addObject:salaryAttribute];
[employeeEntity setClassProperties:empClassProps];
[empClassProps release];

empLockAttributes = [[employeeEntity attributesUsedForLocking]
    mutableCopy];
[empLockAttributes addObject:salaryAttribute];
[employeeEntity setAttributesUsedForLocking:empLockAttributes];
[empLockAttributes release];

This example doesn't illustrate calendar formats or time zones. See the descriptions of the setCalendarFormat:, setServerTimeZone:, and setClientTimeZone: methods for information on these characteristics.

Creating a Derived Attribute

A derived attribute depends on another attribute, so you base it on a definition including that attribute's name rather than on an external name. Because a derived attribute isn't mapped directly to anything in the database, you shouldn't include it in the entity's set of primary key attributes or attributes used for locking:

EOEntity *employeeEntity;    /* Assume this exists. */
EOAttribute *bonusAttribute;
NSArray *empClassProps;

bonusAttribute = [[EOAttribute alloc] initWithName:@"bonus"];
[bonusAttribute setDefinition:@"salary * 0.5"];
[bonusAttribute setValueClassName:"NSNumber"];
[bonusAttribute setValueType:@"d"];
[employeeEntity addAttribute:bonusAttribute];
[bonusAttribute release];

empClassProps = [[employeeEntity classProperties] mutableCopy];
[empClassProps addObject:bonusAttribute];
[employeeEntity setClassProperties:empClassProps];
[empClassProps release];

Creating a Flattened Attribute

A flattened attribute depends on a relationship, so you base it on a definition including that relationship's name rather than on an external name. Because a flattened attribute doesn't correspond directly to anything in its entity's table, you don't have to specify an external name, and shouldn't include it in the entity's set of primary key attributes or attributes used for locking:

EOEntity *employeeEntity;    /* Assume this exists. */
EOAttribute *deptNameAttribute;
NSArray *empClassProps;

deptNameAttribute = [[EOAttribute alloc]
    initWithName:@"departmentName"];
[deptNameAttribute setExternalType:@"varchar"];
[deptNameAttribute setDefinition:@"toDepartment.name"];
[deptNameAttribute setValueClassName:"NSString"];
[deptNameAttribute setExternalType:@"varchar"];
[employeeEntity addAttribute:deptNameAttribute];
[deptNameAttribute release];

empClassProps = [[employeeEntity classProperties] mutableCopy];
[empClassProps addObject:deptNameAttribute];
[employeeEntity setClassProperties:empClassProps];
[empClassProps release];

Instance Variables

 None declared in this class.

Method Types

Initializing new instances	- initWithName:

Getting the entity	- setEntity:
- entity

Setting the name	- setName:
- name
+ isValidName:

Setting date information	+ defaultCalendarFormat
- setCalendarFormat:
- calendarFormat
- setClientTimeZone:
- clientTimeZone
- setServerTimeZone:
- serverTimeZone

Setting external definitions	- setColumnName:
- columnName
- setDefinition:
- definition
- setExternalType:
- externalType

Setting value type information	- setValueClassName:
- valueClassName
- setValueType:
- valueType

Checking type information	- referencesProperty:
- isDerived
- isFlattened
- setReadOnly:
- isReadOnly

Setting SQL statement formats	- setInsertFormat:
- insertFormat
- setSelectFormat:
- selectFormat
- setUpdateFormat:
- updateFormat

Setting the user dictionary	- setUserDictionary:
- userDictionary

Class Methods

defaultCalendarFormat

+ (NSString *)defaultCalendarFormat

Returns a default calendar date format that's used when the EOAttribute doesn't have a calendar date format of its own. This default format is %b %d %Y %H:%M. See the NSDate class specification in the Foundation Kit for more information.

See also:  - setCalendarFormat:

isValidName:

+ (BOOL)isValidName:(NSString *)name

Returns YES if name is a legal name for an attribute, NO otherwise. This method merely sends isValidName: to the EOEntity class with name as the argument.

Instance Methods

calendarFormat

- (NSString *)calendarFormat

Returns the format used when an NSDate object is initialized from a string (typed by the user of a client application, for example), or nil if it hasn't been set. A calendar format applies only to attributes that represent dates. See the NSDate class specification in the Foundation Kit for more information.

See also:  + defaultCalendarFormat, - valueClassName

clientTimeZone

- (NSTimeZone *)clientTimeZone

Returns the time zone used for NSDates in the client application, or the local time zone if one hasn't been set. An EOAdaptorChannel automatically converts dates between the time zones used by the database server and the client when fetching and saving values. Applies only to attributes that represent dates.

See also:  - serverTimeZone, + localTimeZone (NSTimeZone)

columnName

- (NSString *)columnName

Returns the name of the attribute used in communication with the database server, or nil if the attribute isn't simple (that is, if it's derived or flattened). An adaptor uses this name to identify the column corresponding to the attribute. Your application should never need to use this name.

See also:  - definition, - externalType

definition

- (NSString *)definition

Returns a derived or flattened attribute's definition, or nil if the attribute is simple. An attribute's definition is either a value expression defining a derived attribute, such as ªsalary * 12º, or a data path for a flattened attribute, such as ªtoAuthor.nameº.

See also:  - columnName, - externalType

entity

- (EOEntity *)entity

Returns the entity that contains the attribute.

externalType

- (NSString *)externalType

Returns the name the adaptor uses for the attribute's type as it's stored in the database; for example, a Sybase ªvarcharº or an Oracle ªNUMBERº.

See also:  - columnName

initWithName:

- initWithName:(NSString *)name

Initializes a newly allocated EOAttribute with name as its name. The EOAttribute needs to belong to an EOEntity and have a column name or definition before it's usable. This is the designated initializer for the EOAttribute class. Returns self.

See also:  - addAttribute: (EOEntity), - setColumnName:, - setDefinition:

insertFormat

- (NSString *)insertFormat

Returns the format string used for including the attribute's value in a SQL INSERT statement. A %V in this string is replaced by the attribute's value when an INSERT statement is generated.

See also:  - selectFormat, - updateFormat

isDerived

- (BOOL)isDerived

Returns NO if the attribute corresponds exactly to one column in the table associated with its entity, and YES if it doesn't. For example, an attribute with a definition of ªotherAttributeName + 1º is derived. A derived attribute is always read-only.

Note that flattened attributes are also considered as derived attributes.

See also:  - isReadOnly, - isFlattened, - setDefinition:

isFlattened

- (BOOL)isFlattened

Returns YES if the attribute is flattened, NO otherwise. A flattened attribute is one that's accessed through an entity's relationships but belongs to another entity.

Note that flattened attributes are also considered as derived attributes.

See also:  - isDerived, - setDefinition:

isReadOnly

- (BOOL)isReadOnly

Returns YES if the value of the attribute can't be modified, NO if it can. Derived and flattened attributes are always read-only.

See also:  - isDerived

name

- (NSString *)name

Returns the attribute's name.

See also:  - columnName, - definition

referencesProperty:

- (BOOL)referencesProperty:aProperty

Returns YES if aProperty (an EOAttribute or EORelationship) is used in the attribute's external definition, NO otherwise. Only derived attributes reference other properties.

An attribute references a relationship if it's flattened through that relationship. For example, the flattened attribute for an employee's department name (as described in the class description) references the toDepartment relationship of the Employee entity and the name attribute of the Department entity.

See also:  - isDerived

selectFormat

- (NSString *)selectFormat

Returns the format string used for including the attribute's value in a SQL SELECT statement. A %A in this string is replaced by the attribute's external name when a SELECT statement is generated.

See also:  - insertFormat, - updateFormat

serverTimeZone

- (NSTimeZone *)serverTimeZone

Returns the time zone assumed for NSDates in the database server, or the local time zone if one hasn't been set. An EOAdaptorChannel automatically converts dates between the time zones used by the server and the client when fetching and saving values. Applies only to attributes that represent dates.

See also:  - clientTimeZone, + localTimeZone (NSTimeZone)

setCalendarFormat:

- (void)setCalendarFormat:(NSString *)format

Sets to format the format used when an NSDate object is initialized from a string (typed by the user of a client application, for example). This only applies to attributes that represent dates. See the NSDate class specification in the Foundation Kit for more information.

See also:  + defaultCalendarFormat

setClientTimeZone:

- (void)setClientTimeZone:(NSTimeZone *)aTimeZone

Sets to aTimeZone the time zone used for NSDates in the client application. If aTimeZone is nil then the local time zone is used by default. An EOAdaptorChannel automatically converts dates between the time zones used by the database server and the client when fetching and saving values. Applies only to attributes that represent dates.

See also:  - setServerTimeZone:

setColumnName:

- (void)setColumnName:(NSString *)name

Sets to name the name of the attribute used in communication with the database server. An adaptor uses this name to identify the column corresponding to the attribute; this name must match the name of a column in the database table corresponding to the attribute's entity.

This method makes a derived or flattened attribute simple; the definition is released and the column name takes its place for use with the server.

See also:  - setDefiniton:

setDefinition:

- (void)setDefinition:(NSString *)definition

Sets to format the attribute's definition as recognized by the database server. format should be either a value expression defining a derived attribute, such as ªsalary * 12º, or a data path for a flattened attribute, such as ªtoAuthor.nameº.

This method converts a simple attribute into a derived or flattened attribute; the column name is released and the definition takes its place for use with the server.

See also:  - setColumnName:

setEntity:

- (void)setEntity:(EOEntity *)anEntity

Sets the entity of the attribute to anEntity. You only need to use this method when creating a flattened or derived attribute; use EOEntity's addAttribute: to associate an existing attribute with an entity.

See also:  - setDefinition:

setExternalType:

- (BOOL)setExternalType:(NSString *)typeName

Sets to typeName the type used for the attribute in the database adaptor; for example, a Sybase ªvarcharº or an Oracle7 ªNUMBERº. Each adaptor defines the set of types that can be supplied to setExternalType:. The external type you specify for a given attribute must correspond to the type used in the database server.

setInsertFormat:

- (void)setInsertFormat:(NSString *)aString

Sets to aString the format string used for including the attribute's value in a SQL INSERT statement. A %V in this string is replaced by the attribute's value when an INSERT statement is generated. For example, an attribute with an insert format of ª%V + 5º has its value increased by 5 when any enterprise object or row is inserted into the database.

See also:  - setSelectFormat:, - setUpdateFormat:

setName:

- (BOOL)setName:(NSString *)name

Sets the attribute's name to name. Returns YES if successful, NO if name is already in use by another attribute or relationship of the same entity.

setReadOnly:

- (BOOL)setReadOnly:(BOOL)flag

Sets whether the value of the attribute can be modified according to flag and returns YES if successful. Derived and flattened attributes are always read-only; if you try to set one as read-write this method returns NO.

See also:  - isDerived

setSelectFormat:

- (void)setSelectFormat:(NSString *)aString

Sets to aString the format string used for including the attribute's value in a SQL SELECT statement. A %A in this string is replaced by the attribute's external name when a SELECT statement is generated. For example, setting the salary attribute's select format to ª%A * 12º causes its value to be multiplied by 12 as soon as it's fetched from the server.

See also:  - setInsertFormat:, - setUpdateFormat:

setServerTimeZone:

- (void)setServerTimeZone:(NSTimeZone *)aTimeZone

Sets to aTimeZone the time zone used for NSDates in the database server. If aTimeZone is nil then the local time zone is used by default. An EOAdaptorChannel automatically converts dates between the time zones used by the server and the client when fetching and saving values. Applies only to attributes that represent dates.

See also:  - setClientTimeZone:

setUpdateFormat:

- (void)setUpdateFormat:(NSString *)aString

Sets to aString the format string used for including the attribute's value in a SQL UPDATE statement. A %V in this string is replaced by the attribute's value when an UPDATE statement is generated. For example, an attribute with an update format of ª%V + 5º has its value increased by 5 when it's updated in the database.

See also:  - setInsertFormat:, - setSelectFormat:

setUserDictionary:

- (void)setUserDictionary:(NSDictionary *)aDictionary

Sets the dictionary of auxiliary data, which your application can use for whatever it needs. The dictionary must be a property list (that is, it must contain only NSString, NSData, NSArray, or NSDictionary objects).

setValueClassName:

- (void)setValueClassName:(const char *)name

Sets the attribute's value class name to name. When an EOAdaptorChannel fetches data for the attribute, it's presented to the application as an instance of this class.

The class need not exist in the run-time system when this message is sent, but it must exist when an adaptor channel performs a fetch; if the class isn't present the result depends on the adaptor. See your adaptor's documentation for information on how absent value classes are handled.

See also:  - setValueType:

setValueType:

- (void)setValueType:(NSString *)typeName

Sets to typeName the format type for custom value classes, such as ªTIFFº or ªRTFº. This type name is used with the EODatabaseCustomValues protocol to identify data formats for custom values.

See also:  - setValueClassName:

updateFormat

- (NSString *)updateFormat

Returns the format string used for including the attribute's value in a SQL UPDATE statement. A %V in this string is replaced by the attribute's value when an UPDATE statement is generated.

See also:  - insertFormat, - selectFormat

userDictionary

- (NSDictionary *)userDictionary

Returns a dictionary of user data. Your application can use this to store any auxiliary information it needs. This dictionary is a property list (that is, it contains only NSString, NSData, NSArray, or NSDictionary objects).

valueClassName

- (const char *)valueClassName

Returns the name of the class for value types (standard or custom). When data is fetched for the attribute, it's presented to the application as an instance of this class. For example, if a column from the database is represented by instances of NXImage this method returns ªNXImageº.

This class must be present in the run-time system when an EOAdaptorChannel fetches data for the attribute; if the class isn't present the result depends on the adaptor. See your adaptor's documentation for information on how absent value classes are handled.

See also:  - valueType

valueType

- (NSString *)valueType

Returns the format type for custom value classes, such as ªTIFFº or ªRTFº. This type name is used with the EODatabaseCustomValues protocol to identify data formats for custom values.

See also:  - valueClassName